(** List zippers
  
    This module implements zipper of lists allowing to have a cursor
    on lists.  *)


type 'a t = 'a list * 'a list
  (** The type of zipper of elements of type ['a]  *)

exception Out_of_bound
  (** Raised when a zipper is accessed out of bounds  *)

exception End_of_zip
  (** Raised when at the end of the zippper  *)

val empty : 'a t
  (** The empty zipper  *)
val next : 'a t -> 'a t
  (** [next z] moves the cursor to the next element in [z] *)
val previous : 'a t -> 'a t
  (** [previous z] moves the cursor to the previous element in [z] *)
val first : 'a t -> 'a t
  (** [first z] moves the cursor to the first element in [z] *)
val last : 'a t -> 'a t
  (** [last z] moves the cursor after the last element in [z] *)
val get : 'a t -> 'a
  (** [get z] reads the value under the cursor in [z]  *)
val insert : 'a -> 'a t -> 'a t
  (** [insert e z] inserts the element [e] where the cursor is in [z]  *)
val delete : 'a t -> 'a t
  (** [delete z] deletes the element under the cursor in [z]  *)
val replace : 'a -> 'a t -> 'a t
  (** [replace e z] replaces the element under the cursor in [z] with [e]. This
      is equivalent to [insert e (delete z)] *)
val rev : 'a t -> 'a t
  (** [rev z] reverses the zipper  *)
val append : 'a t -> 'a t -> 'a t
  (** [append z z'] appends [z] to [z'], the cursor position is where it was in
      [z'] *)
val iter : ('a -> unit) -> 'a t -> unit
  (** [iter f z] applies [f] to each element of [z]  *)
val chop : 'a t -> 'a t
  (** [chop z] deletes all element after the cursor in [z]. The cursor position
      is the at the end of [z] *)
val from_list : 'a list -> 'a t
  (** [from_list l] converts [l] into a zipper. The cursor is positionned at the
      beginning.  *)
val to_list : 'a t -> 'a list
  (** [to_list z] converts [z] into a list.  *)
val length : 'a t -> int
